//@version=5
indicator("High-Prob Break & Reject + Trendline (15m)", overlay=true, max_lines_count=500)

// ---------------------------
// INPUTS
// ---------------------------
pivotLen = input.int(5, "Pivot Strength")
zoneATRmult = input.float(0.5, "Zone Thickness (ATR Multiplier)", step=0.1)
atrLen = input.int(14, "ATR Length")
emaTrendLen = input.int(200, "EMA Trend Filter")

// ---------------------------
// TREND FILTER
// ---------------------------
emaTrend = ta.ema(close, emaTrendLen)
upTrend = close > emaTrend
downTrend = close < emaTrend

plot(emaTrend, "EMA200", color=color.new(color.blue, 70), linewidth=1)

// ---------------------------
// S/R PIVOTS & ZONES
// ---------------------------
pivotHigh = ta.pivothigh(high, pivotLen, pivotLen)
pivotLow  = ta.pivotlow(low,  pivotLen, pivotLen)

atr = ta.atr(atrLen)
zoneSize = atr * zoneATRmult

var float lastRes = na
var float lastSup = na

if not na(pivotHigh)
    lastRes := pivotHigh
if not na(pivotLow)
    lastSup := pivotLow

resTop = lastRes + zoneSize
resBottom = lastRes - zoneSize
supTop = lastSup + zoneSize
supBottom = lastSup - zoneSize

plot(resTop, "Resistance Top", color=color.new(color.red, 70))
plot(resBottom, "Resistance Bottom", color=color.new(color.red, 70))
plot(supTop, "Support Top", color=color.new(color.green, 70))
plot(supBottom, "Support Bottom", color=color.new(color.green, 70))

// ---------------------------
// TRENDLINE SYSTEM (3 touches + ray)
// ---------------------------
var highsY = array.new_float()
var highsX = array.new_int()
var lowsY  = array.new_float()
var lowsX  = array.new_int()

if not na(pivotHigh)
    array.push(highsY, pivotHigh)
    array.push(highsX, bar_index)

if not na(pivotLow)
    array.push(lowsY, pivotLow)
    array.push(lowsX, bar_index)

has3Highs = array.size(highsY) >= 3
has3Lows  = array.size(lowsY)  >= 3

float downSlope = na
float downIntercept = na
float upSlope = na
float upIntercept = na

if has3Highs
    float y1 = array.get(highsY, array.size(highsY)-3)
    float y2 = array.get(highsY, array.size(highsY)-1)
    float x1 = array.get(highsX, array.size(highsX)-3)
    float x2 = array.get(highsX, array.size(highsX)-1)
    downSlope := (y2 - y1) / (x2 - x1)
    downIntercept := y1 - downSlope * x1

if has3Lows
    float y1 = array.get(lowsY, array.size(lowsY)-3)
    float y2 = array.get(lowsY, array.size(lowsY)-1)
    float x1 = array.get(lowsX, array.size(lowsX)-3)
    float x2 = array.get(lowsX, array.size(lowsX)-1)
    upSlope := (y2 - y1) / (x2 - x1)
    upIntercept := y1 - upSlope * x1

downRay = has3Highs ? downSlope * bar_index + downIntercept : na
upRay   = has3Lows  ? upSlope   * bar_index + upIntercept  : na

// ---------------------------
// TRENDLINE BREAK
// ---------------------------
upTrendBreak = has3Lows  and close < upRay       // bearish → sell
downTrendBreak = has3Highs and close > downRay  // bullish → buy

// ---------------------------
// FLEXIBLE BREAK → REJECT LOGIC
// ---------------------------
var bool brokeAboveRes = false
var bool brokeBelowSup = false

if close > resTop
    brokeAboveRes := true
if close < supBottom
    brokeBelowSup := true

rejectRes = brokeAboveRes and close < resBottom
rejectSup = brokeBelowSup and close > supTop

// ---------------------------
// SIGNALS WITH TREND FILTER
// ---------------------------
sellSignal = rejectRes and upTrendBreak and downTrend
buySignal  = rejectSup and downTrendBreak and upTrend

if sellSignal
    brokeAboveRes := false
if buySignal
    brokeBelowSup := false

// ---------------------------
// PLOT SIGNALS
// ---------------------------
plotshape(buySignal, title="Buy Signal", style=shape.labelup, location=location.belowbar,
     color=color.green, size=size.tiny, text="BUY")
plotshape(sellSignal, title="Sell Signal", style=shape.labeldown, location=location.abovebar,
     color=color.red, size=size.tiny)

// ---------------------------
// ALERT CONDITIONS
// ---------------------------
alertcondition(buySignal, "Buy Signal", "High-Prob BUY Signal")
alertcondition(sellSignal, "Sell Signal", "High-Prob SELL Signal")
